#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Time     : 2018/8/24 10:52
# @Author   : crabtesting@163.com
# @File     : jiraCase.py
from openpyxl.reader.excel import load_workbook
import jira
import json
import re
import os
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
Url = "http://jira.test.com.cn"
UserName = "username"
Password = "password"
Project = "运营技术-BBS"
IssueType = "测试"
Sprints = {}
def jiraCase():
    exedir = os.path.dirname(os.path.realpath(__file__))
    # 登录Jira
    jac = jira.JIRA(Url, basic_auth=(UserName, Password))
    # 准备工作：读取caseData.txt中存储的 case start的行、Project对应的id、IssueType对应的id
    # 如果 存储的Project对应的id和IssueType对应的id 失效，则重新获取
    caseStartNum, projectdict, issuedict, projectId, issueId =  get_issueCom(exedir,jac)
    # 从表jiraCase.xlsx读取case
    allValues,caseStartNumNew = get_allCase(exedir, caseStartNum)
    #轮询创建 Jira
    for Values in allValues:
        if Values == []:
            continue
        print(Values[0][0])
        RelatesTo = Values[0][5]
        Sprint = dealSprint(jac,RelatesTo)
        jiraname = dealTest(jac,projectId,issueId,RelatesTo,Values,Sprint,Url,UserName,Password)
        if not os.path.exists("%s/alljiracase"%(exedir)):
            os.mkdir("%s/alljiracase"%(exedir))
        write_case_csv(jiraname,Values,exedir)
    if caseStartNumNew != caseStartNum-1:
        update_caseData(exedir, caseStartNumNew, projectdict, issuedict)
    else:
        print(caseStartNumNew)

def write_case_csv(jiraname,Values,exedir):
    summary = Values[0][0]
    description = Values[0][1]
    fileName = "%s %s"%(jiraname,summary)
    if len(fileName) > 250:
        fileName = fileName[0:250]
    while True:
        try:
            file = open("%s/alljiracase/%s.csv"%(exedir,fileName),"w",encoding="ANSI")
            break
        except:
            print("\033[0;30;41m%s/alljiracase/%s.csv\033[0m  回车继续："%(exedir,fileName))
            input("\033[0;30;41m文件被其他进程占用，请手动解除占用\033[0m  回车继续：")
    newValues = "name,description,step,testdata,result"
    for value in Values:
        com = "\n\"%s\n\",\"%s\n\",\"%s\n\",\"%s\n\",\"%s\n\""%(summary,description,value[2],value[3],value[4])
        newValues += com
    file.write(newValues)
    file.close()
    pass

def get_issueCom(exedir,jac):
    # 读取caseData.txt中存储的 case start的行、Project对应的id、IssueType对应的id
    # 如果 存储的Project对应的id和IssueType对应的id 失效，则重新获取
    jiraFlag = True
    caseStartNum = 1
    if os.path.exists("%s/caseData.txt" % (exedir)):
        caseData = open("%s/caseData.txt" % (exedir), "r", encoding='UTF-8').read().strip()
        while caseData[0] != "[":
            caseData = caseData[1:]
        caseData = json.loads(caseData.strip())
        if isinstance(caseData, list) and len(caseData) == 3:
            projectdict = caseData[1]
            issuedict = caseData[2]
            if int(caseData[0]) > 1:
                caseStartNum = int(caseData[0])
            if Project in projectdict and IssueType in issuedict:
                try:
                    cc = jac.createmeta(projectKeys=projectdict[Project], issuetypeIds=issuedict[IssueType])
                    jiraFlag = False
                except:
                    pass
    # 无效，重新获取相关信息
    if jiraFlag:
        projectname = jac.projects()
        projectdict = {}
        for xx in projectname:
            projectdict[xx.name] = xx.key
        issuename = jac.createmeta(projectKeys=projectdict[Project])["projects"][0]["issuetypes"]
        issuedict = {}
        for xx in issuename:
            issuedict[xx["name"]] = xx["id"]
        cc = jac.createmeta(projectKeys=projectdict[Project], issuetypeIds=issuedict[IssueType])
    projectId = cc['projects'][0]["id"]
    issueId = cc['projects'][0]["issuetypes"][0]["id"]
    return caseStartNum+1, projectdict, issuedict, projectId, issueId

def update_caseData(exedir,caseStartNum, projectdict, issuedict):
    caseData = [caseStartNum, projectdict, issuedict]
    caseData = json.dumps(caseData,ensure_ascii=False)
    open("%s/caseData.txt" % (exedir), "w", encoding='UTF-8').write(caseData)

def get_allCase(exedir,caseStartNum):
    # 从表jiraCase.xlsx读取case
    # 结构：
    #      name      |  description   |   step    |  testdata    |  result    |   LinkTo
    #      标题        |  描述          |  测试步骤  |    测试数据    |  预期结果  |   关联的Jira单号
    # 注意：
    #      创建一个Jira，必须且只要在第一个填写“标题”、“描述”、“关联的Jira单号”
    filedir = "%s/jiraCase.xlsx" % (exedir)
    wb = load_workbook(filename=filedir)
    ws = wb.worksheets[0]
    value = []
    Values = []
    allValues = []
    maxNum = ws.max_row
    for i in range(ws.max_row - caseStartNum + 1):
        j = "%s" % (i + caseStartNum)
        value = []
        for ii in ws[j]:
            ccc = "%s" % (ii.value)
            value.append(ccc)
            if len(value) >= 8:
                break
        if (value[2] == "None" and value[3] == "None") or (value[0] != "None" and value[5] == "None") or (Values == [] and value[0] == "None"):
            maxNum = i + caseStartNum - 1
            break
        if value[0] != "None" and Values != []:
            allValues.append(Values)
            Values = []
        Values.append(value)
    allValues.append(Values)
    caseStartNum = maxNum
    return allValues,caseStartNum

def dealSprint(jac,RelatesTo):
    if RelatesTo not in Sprints:
        cc = jac.issue(RelatesTo)
        dd = cc.__dict__
        dd = dd["raw"]["fields"]["customfield_10104"]
        Sprint = re.search("id=(\d+)",dd[0]).group(1)
        Sprints[RelatesTo] = int(Sprint)
    return Sprints[RelatesTo]

def dealTest(jac,projectId,issueId,RelatesTo,Values,Sprint,Url,UserName,Password):
    fielddict = {}
    value = Values[0]
    fielddict["project"] = {"id": projectId}
    fielddict["issuetype"] = {"id": issueId}
    fielddict["summary"] = "%s -- %s"%(IssueType,value[0])
    fielddict["description"] = value[1]
    fielddict["assignee"] = {"name":UserName}
    customfield_10104 = Sprint
    # jiraname = "POSTTRADE-3173"
    flag = True
    try:
        jiraname = jac.create_issue(fields=fielddict)
        flag = True
    except:
        flag = False
        print(u"【ERROR】测试项目创建失败")
    if flag:
        try:
            if customfield_10104:
                jac.issue(jiraname).update(customfield_10104=customfield_10104)
                print(u"%s 测试项目创建成功,Sprint关联成功"%(jiraname))
            else:
                print(u"%s 测试项目创建成功 %s"%(jiraname))
        except:
            print(u"%s 测试项目关联sprint失败"%(jiraname))

        driver = webdriver.Chrome()
        driver.get(Url)
        driver.find_element_by_id("login-form-username").send_keys(UserName)
        driver.find_element_by_id("login-form-password").send_keys(Password)
        driver.find_element_by_id('login').click()
        time.sleep(1)
        url1 = "%s/browse/%s"%(Url,jiraname)
        driver.get(url1)
        for i in Values:
            if i[2] != "None":
                for ii in range(600):
                    try:
                        driver.find_element_by_xpath("//*[@id=\"project-config-steps-table\"]/tbody[2]/tr/td[6]/div/input")
                        break
                    except:
                        time.sleep(0.1)
                try:
                    driver.find_elements_by_name("step")[i].send_keys(i[2])
                    driver.find_elements_by_name("data")[i].send_keys(i[3])
                    driver.find_elements_by_name("result")[i].send_keys(i[4])
                except:
                    time.sleep(1)
                    driver.find_elements_by_name("step")[0].send_keys(i[2])
                    driver.find_elements_by_name("data")[0].send_keys(i[3])
                    driver.find_elements_by_name("result")[0].send_keys(i[4])
                driver.find_element_by_xpath("//*[@id=\"project-config-steps-table\"]/tbody[2]/tr/td[6]/div/input").click()
        try:
            driver.find_element_by_id("opsbar-zephyr-je-manage-plan-top_more").click()
            driver.find_element_by_id("zfj-link-issue").click()
            time.sleep(3)
            xxx = driver.find_element_by_id("jira-issue-keys-textarea")
            xxx.send_keys(RelatesTo)
            ActionChains(driver).move_by_offset(-1, -1).click().perform()
            driver.find_element_by_xpath("//*[@id=\"link-jira-issue\"]/div[2]/div/input").click()
        except:
            print(u"%s linkto失败" % (jiraname))
        return jiraname

if __name__ == '__main__':
    jiraCase()